/*
 * Copyright (c) 2011, Julien Lamy
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice,
 * this list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright
 * notice, this list of conditions and the following disclaimer in the
 * documentation and/or other materials provided with the distribution.
 *
 * Neither the name of the project's author nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */

#ifndef c268cc54_3fd9_4405_80c5_beb9a599bd15
#define c268cc54_3fd9_4405_80c5_beb9a599bd15

#include <iosfwd>
#include <set>

#include "config.h"

/**
 * @brief Read the binary representation of a member variable from a stream.
 */
#define READ_TO_VARIABLE(name, type, stream) \
    stream.read(reinterpret_cast<char*>(&name), sizeof(type));

/**
 * @brief Declare a variable of given type, and read its binary representation
 * from stream.
 */
#define DEFINE_AND_READ(name, type, stream) \
    type name; \
    READ_TO_VARIABLE(name, type, stream);

/**
 * @brief Test if stream is positioned at the start of a chunk of given_type.
 */
BABELPOD_EXPORT bool is_chunk_of_type(std::istream & stream, char const* wanted_type);

/**
 * @brief Create a set from any iterator range, keeping only elements that match
 * the given predicate.
 */
template<typename Iterator, typename UnaryFunction>
std::set<typename UnaryFunction::result_type>
unique_set(Iterator const & begin, Iterator const & end, UnaryFunction const & f)
{
    std::set<typename UnaryFunction::result_type> result;
    for(Iterator current = begin; current != end; ++current)
    {
        result.insert(f(*current));
    }

    return result;
}

#endif // c268cc54_3fd9_4405_80c5_beb9a599bd15
